﻿Imports System.Windows.Input

Public NotInheritable Class SimpleCommand
    Implements ICommand

#Region " Declarations "

    Private ReadOnly _canExecute As Predicate(Of Object)
    Private ReadOnly _execute As Action(Of Object)

#End Region

#Region "Event Handler"

    Public Custom Event CanExecuteChanged As EventHandler _
        Implements ICommand.CanExecuteChanged

        AddHandler(ByVal value As EventHandler)
            If _canExecute IsNot Nothing Then
                AddHandler CommandManager.RequerySuggested, value
            End If
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            If _canExecute IsNot Nothing Then
                RemoveHandler CommandManager.RequerySuggested, value
            End If
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            If _canExecute IsNot Nothing Then
                CommandManager.InvalidateRequerySuggested()
            End If
        End RaiseEvent
    End Event

#End Region

#Region "Constructor"

    Public Sub New(ByVal execute As Action(Of Object))
        Me.New(execute, Nothing)
    End Sub

    Public Sub New(ByVal execute As Action(Of Object), _
                   ByVal canExecute As Predicate(Of Object))
        If execute Is Nothing Then
            Throw New ArgumentNullException("execute delegate cannot be null")
        End If

        _execute = execute
        _canExecute = canExecute
    End Sub

#End Region

#Region "Methods"

    <DebuggerStepThrough()> _
    Public Function CanExecute(ByVal param As Object) As Boolean _
        Implements ICommand.CanExecute

        If _canExecute Is Nothing Then
            Return If(_canExecute Is Nothing, True, _canExecute(param))
        End If

        Return _canExecute(param)
    End Function

    Public Sub Execute(ByVal param As Object) _
        Implements ICommand.Execute

        _execute(param)
    End Sub

#End Region

End Class

Public NotInheritable Class SimpleCommand(Of T)
    Implements ICommand

#Region " Declarations "

    Private ReadOnly _canExecute As Predicate(Of T)
    Private ReadOnly _execute As Action(Of T)

#End Region

#Region " Events "

    Public Custom Event CanExecuteChanged As EventHandler Implements System.Windows.Input.ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)
            If _canExecute IsNot Nothing Then
                AddHandler CommandManager.RequerySuggested, value
            End If
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            If _canExecute IsNot Nothing Then
                RemoveHandler CommandManager.RequerySuggested, value
            End If
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            If _canExecute IsNot Nothing Then
                CommandManager.InvalidateRequerySuggested()
            End If
        End RaiseEvent
    End Event

#End Region

#Region " Constructors "

    Public Sub New(ByVal execute As Action(Of T))
        Me.New(execute, Nothing)
    End Sub

    Public Sub New(ByVal execute As Action(Of T), ByVal canExecute As Predicate(Of T))

        If execute Is Nothing Then
            Throw New ArgumentNullException("execute", "Delegate comamnds can not be null")
        End If

        _execute = execute
        _canExecute = canExecute
    End Sub

#End Region

#Region " Methods "

    <DebuggerStepThrough()> _
    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute

        If _canExecute Is Nothing Then
            Return True

        Else
            Return _canExecute(DirectCast(parameter, T))
        End If

    End Function

    Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
        _execute(DirectCast(parameter, T))
    End Sub

#End Region

End Class
